/*
 * @Author: your name
 * @Date: 2021-07-08 15:11:00
 * @LastEditTime: 2022-11-08 14:14:01
 * @LastEditors: chen_yt
 * @Description: In User Settings Edit
 * @FilePath: \central-system\src\permission.js
 */
import router from './router'
import NProgress from 'nprogress' // progress bar
import 'nprogress/nprogress.css' // progress bar style
import store from '@/store'
import { localRoute, mainApp, subApp } from '@/config'
import { PERMISSIONS, BEHAVIOR_ANALYSIS, IS_SAAS_MODE } from '@/store/Getter/getterTypes'
import { UPDATE_PERMISSION_QUEUE } from '@/store/Mutation/mutationTypes'
import { PERMISSION } from '@/store/State/stateTypes'
import { GET_PERMISSIONS } from '@/store/Action/actionTypes'
import { getDate, getTitle } from '@/utils/monitor'
import { addMonitor } from '@/api/app'
import storage from '@/utils/storage'
import { Notification } from 'fawkes-lib'
import Vue from 'vue'
import { getReplacedFunction } from '@/microapp/utilCenter'

import { GuardsList } from './routerGuards'


NProgress.configure({ showSpinner: false }) // NProgress Configuration
function removeLoading() {
  let loading = document.getElementById('main-loading')
  loading && loading.parentNode.removeChild(loading)
  loading = null
}

let guardsList = new GuardsList()

router.beforeEach((to, from, next) => {
  // start progress bar
  NProgress.start()
  
  let modeName = 'normal'

  switch (true) {
    case Vue.prototype.$InQianKun: {
      modeName = 'inqiankun'
      break
    }
    case subApp: {
      modeName = 'subapp'
      break
    }
    case mainApp: {
      modeName = 'mainapp'
      break
    }

    default:
  }

  let Guards = guardsList.getGuard(modeName, to, from, next)
  if (!Guards.routeRedirect()) {
    Guards.routeResolve()
  }
})

router.beforeResolve(async (to, from, next) => {
  if (localRoute || !to.meta || !to.meta.menuId || store.state[PERMISSION][to.meta.menuId]) {
    next()
    return false
  }
  //获取按钮权限
  await store.dispatch(GET_PERMISSIONS, to.meta.menuId)
  next()

})

router.afterEach((to, from) => {
  let prefix = Vue.prototype.$appBasePath
  if (to.path == prefix + '/distribute') {
    router.replace(prefix +'/home')
  }

  let redirect = storage.get('redirectUrl')

  if (redirect == to.fullPath) {
    storage.remove('redirectUrl')
  }

  if (store.getters[BEHAVIOR_ANALYSIS] && storage.get('access_token')) {
    if (from?.name && to?.name) {
      addMonitor({
        ev: 'click',//点击事件
        fun: '页面切换',
        mc: to.name,//模块编码
        mn: getTitle(to.name) || to.name,//模块名称
        pa: to.fullPath,//当前页面路由路径
        fpa: from.fullPath,//前置页面路由路径
        fc: from.name,//前置页面模块编码
        fn: getTitle(from.name) || from.name,//前置页面模块名称
        dur: getDate(storage.get('enterTime'), new Date()),//前置页面停留时间
        url: document.location.href,//当前url地址
        sr: `${window.screen.height}x${window.screen.width}`,//屏幕分辨率
        nt: navigator?.connection?.effectiveType,//网络类型
        fl: store.getters.language || '',//当前系统语言
        lan: navigator.language, //浏览器语言
        depthId: storage.get('depthId')//用户访问深度ID
      })
    }
    if (to?.name) {
      storage.set('enterTime', new Date())
    }
  }
  // finish progress bar
  NProgress.done()
  removeLoading()
})

router.onError((error) => {
  Notification.error({
    title: '错误',
    message: '加载的页面发生异常',
  })

  console.error(error)
  NProgress.done()
  removeLoading()
})

export default router

/**
 * @description: 通过code查询用户权限是否已授权
 * @param {String} code 权限编码
 * @param {Object} params 鉴权参数  {Boolean} notFlag 反查标识 | {Array} types 作用门户等级 | {Boolean} entire 全量
 * @return: Boolean
 */
const nodePermission = function (codes = [], params = {}) {
  if (params?.types && store.getters.multiPortal && !params.types.find(type => type == store.state.portal.type)) {
    return true
  }

  let checkCode = (attr) => {
    return store.getters[PERMISSIONS].find(function (item) {
      return attr && attr == item.code
    })
  }

  let findValue

  if (codes instanceof Array) {
    if (params?.entire) {
      findValue = codes.every(code => {
        return code && checkCode(code)
      })
    }
    else {
      findValue = codes.some(code => {
        return code && checkCode(code)
      })
    }
  } else {
    findValue = checkCode(codes)
  }

  checkCode = null

  const rvalue = !!findValue
  return localRoute ? true : (params?.notFlag ? !rvalue : rvalue)
}

const dataPermission = (code, types) => {
  if (types && store.getters.multiPortal && !types.find(type => type == store.state.portal.type)) {
    return true
  }

  let has = store.getters[PERMISSIONS].find(p => p.code == code)
  has && store.commit(UPDATE_PERMISSION_QUEUE, has)
  return !!has
}

const redirectTo = (url) => {
  let to = '/home'
  if (url) {
    to = url
  }
  if (storage.get('redirect') == 1) {
    to = storage.get('redirectUrl') ? storage.get('redirectUrl') : '/home'
    storage.remove('redirect')
  }
  if (store.getters[IS_SAAS_MODE]) {
    to = '/tenantselect'
  }
  if (to == '/home'){
    to = '/distribute'
    storage.set('changePortal', 1);
  }
  location.replace(location.href.replace(router.currentRoute.path, to))
}

const dataPermissionAfterReplaced = getReplacedFunction('dataPermission', dataPermission)
const nodePermissionAfterReplaced = getReplacedFunction('nodePermission', nodePermission)

export {
  nodePermissionAfterReplaced as nodePermission,
  dataPermissionAfterReplaced as dataPermission,
  redirectTo
}